package com.qhx.backme.service.impl;

import cn.hutool.json.JSONArray;
import com.qhx.backme.model.Result;
import com.qhx.backme.model.vo.ReceiptVO;
import com.qhx.backme.model.vo.UserEntityVO;
import com.qhx.backme.model.vo.UserVO;
import com.qhx.backme.service.QueryService;
import com.qhx.backme.util.HttpUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;

/**
 * 实现查询服务接口的类
 * 提供了对公司和银行信息的查询功能，以及凭证信息的获取
 *
 * @author: qhx20040819
 * @date: 2023-10-23 19:34
 **/
@Service
public class QueryServiceImpl implements QueryService
{

    @Autowired
    private HttpUtil httpUtil;

    @Override
    public Result listCompany(String userAddress)
    {
        // 查询公司列表
        return listUser(userAddress, "company");
    }

    @Override
    public Result listBank(String userAddress)
    {
        // 查询银行列表
        return listUser(userAddress, "bank");
    }

    /**
     * 根据用户类型查询用户列表
     *
     * @param userAddress 用户地址
     * @param type        用户类型，"company" 或 "bank"
     * @return 查询结果
     */
    private Result listUser(String userAddress, String type)
    {
        String funName = null;
        if (type.equals("company"))
        {
            funName = "getAllCompanyAddress";
        }

        if (type.equals("bank"))
        {
            funName = "getAllBankAddress";
        }

        JSONArray call = httpUtil.call(userAddress, funName, new ArrayList<>());
        JSONArray jsonAddressS = call.getJSONArray(0);
        JSONArray resAry = new JSONArray();
        for (int i = 0; i < jsonAddressS.size(); i++)
        {
            String address = jsonAddressS.getStr(i);
            UserVO userVO = getUserVO(address, type);
            resAry.add(userVO);
        }
        return Result.success(resAry);
    }


    /**
     * 用公司(银行)地址、用户类型，获取公司实体信息
     *
     * @param address 用户地址
     * @param type    用户类型，"company" 或 "bank"
     * @return 用户信息对象
     */
    private UserVO getUserVO(String address, String type)
    {
        String contractFun = null;
        Integer userType = null;
        if (type.equals("company"))
        {
            contractFun = "getCompany";
            userType = 1;
        }

        if (type.equals("bank"))
        {
            contractFun = "getBank";
            userType = 2;
        }
        ArrayList<Object> params = new ArrayList<>();
        params.add(address);
        JSONArray jsonUser = httpUtil.call(address, contractFun, params);
        UserVO userVO = new UserVO();
        userVO.setName(jsonUser.getStr(0));
        userVO.setAddress(jsonUser.getStr(1));
        userVO.setCreditAsset(jsonUser.getInt(2));
        userVO.setSendReceiptIndex(jsonUser.getJSONArray(3));
        userVO.setAcceptReceiptIndex(jsonUser.getJSONArray(4));
        userVO.setType(userType);
        return userVO;
    }

    /**
     * 用凭证索引列表来获取凭证列表
     *
     * @param indexList 凭证索引列表
     * @return 凭证列表
     */
    private List<ReceiptVO> getReceiptVOListByIndexList(String userAddress, JSONArray indexList)
    {
        ArrayList<ReceiptVO> receiptVOS = new ArrayList<>();
        for (int i = 0; i < indexList.size(); i++)
        {
            Integer receiptIndex = indexList.getInt(i);
            ReceiptVO receiptVO = getReceiptVOByIndex(userAddress, receiptIndex);
            receiptVOS.add(receiptVO);
        }
        return receiptVOS;
    }

    /**
     * 用凭证索引来获取凭证
     *
     * @param receiptIndex 凭证索引
     * @return 凭证对象
     */
    private ReceiptVO getReceiptVOByIndex(String userAddress, Integer receiptIndex)
    {
        List<Object> params = new ArrayList<>();
        params.add(receiptIndex);
        JSONArray jsonReceipt = httpUtil.call(userAddress, "getReceipt", params);
        ReceiptVO receiptVO = new ReceiptVO();
        receiptVO.setId(receiptIndex);
        receiptVO.setSenderAddress(jsonReceipt.getStr(0));
        receiptVO.setAccepterAddress(jsonReceipt.getStr(1));
        receiptVO.setReceiptType(jsonReceipt.getInt(2));
        receiptVO.setTransferType(jsonReceipt.getInt(3));
        receiptVO.setAmount(jsonReceipt.getInt(4));
        return receiptVO;
    }


    @Override
    public Result listAllReceipt(String userAddress)
    {
        // 查询所有凭证
        JSONArray call = httpUtil.call(userAddress, "receiptIndex", new ArrayList<>());
        Integer receiptIndex = call.getInt(0);
        ArrayList<ReceiptVO> receiptVOS = new ArrayList<>();
        for (Integer i = 1; i <= receiptIndex; i++)
        {
            ReceiptVO receiptVO = getReceiptVOByIndex(userAddress, i);
            // 判断是否属于该用户
            if (receiptVO.getSenderAddress().equals(userAddress) || receiptVO.getAccepterAddress().equals(userAddress))
            {
                receiptVOS.add(receiptVO);
            }
        }
        return Result.success(receiptVOS);
    }

    @Override
    public Result<UserEntityVO> getCompanyEntity(String userAddress, String queryAddress)
    {
        // 获取公司实体信息
        return getUserEntity(userAddress, queryAddress, "company");
    }

    @Override
    public Result<UserEntityVO> getBankEntity(String userAddress, String queryAddress)
    {
        // 获取银行实体信息
        return getUserEntity(userAddress, queryAddress, "bank");
    }

    /**
     * 根据用户类型获取用户实体信息
     *
     * @param userAddress  用户地址
     * @param queryAddress 查询地址
     * @param type         用户类型，"company" 或 "bank"
     * @return 用户实体信息对象
     */
    private Result<UserEntityVO> getUserEntity(String userAddress, String queryAddress, String type)
    {
        UserVO userVO = getUserVO(queryAddress, type);
        // 获取用户凭证索引
        JSONArray sendReceiptIndex = userVO.getSendReceiptIndex();
        JSONArray acceptReceiptIndex = userVO.getAcceptReceiptIndex();
        // 获取凭证索引列表
        List<ReceiptVO> senderReceiptList = getReceiptVOListByIndexList(userAddress, sendReceiptIndex);
        List<ReceiptVO> accepterReceiptList = getReceiptVOListByIndexList(userAddress, acceptReceiptIndex);
        UserEntityVO userEntityVO = new UserEntityVO();
        userEntityVO.setUserVO(userVO);
        userEntityVO.setSenderReceiptList(senderReceiptList);
        userEntityVO.setAccepterReceiptList(accepterReceiptList);
        return Result.success(userEntityVO);
    }

}
